#ifndef SCHEME_H_
#define SCHEME_H_

#include <string>
#include <cstring>
#include <functional>
#include <algorithm>
#include "MetaDirectory.h"
#include "MetaFile.h"

namespace Validator
{


//! Scheme trieda.
/*!
 	Trieda predstavuje reprezentaciu XML dokumentu na definiciu validneho
	archivacneho suboru pre dany predmet
*/
class Scheme
{
	public:

		//! Constructor
		/*!
			Default konstruktor
		*/
		Scheme(void);

		//! Constructor
		/*!
 			Zakladny konstruktor triedy
			\param theName nazov predmetu pre ktory je urcena schema
			\param theType typ archivacneho suboru
		*/
		Scheme(std::string theName,const char *theType);

		//! Copy constructor
		/*!
			\param objekt rovnakeho typu
		*/
		//Scheme(const Scheme& theScheme);

		//! Destructor
		/*!
		*/
		~Scheme(void);

		//! Assign operator overloading
		/*!
		*/
		//Scheme& Scheme::operator=(const Scheme& scheme);

		//! Operator Porovnania (rovnasa)
		/*!
			Sluzi na porovnanie 2 Scheme ci sa rovnaju
			\return true ak sa rovnaju, false inak
		*/
		bool operator==(Scheme theOther);

		//! Operator Porovnania (nerovnasa)
		/*!
			Sluzi na porovnanie 2 Scheme ci sa erovnaju
			\return true ak sa nerovnaju, false inak
		*/
		bool operator!=(Scheme &theOne);

		//! Add
		/*!
 			Funkcia na pridanie prvku do schemy
			\param theDirectory prida jeden adresar do schemy
		*/
		void Add(MetaDirectory theDirectory);

		//! Add
		/*!
 			Funkcia na pridanie prvku do schemy
			\param theDirectory prida jeden subor do schemy
		*/
		void Add(MetaFile  theFile);

		//! GetDirectories
		/*!
 			Funkcia navrati vsetky korenove adresare
			\return kolekcia(vektor) adresarov
		*/
		std::vector<MetaDirectory> &GetDirectories();

		//! GetFiles
		/*!
 			Funkcia navrati vsetky korenove subory
			\return kolekcia(vektor) suborov
		*/
		std::vector<MetaFile> GetFiles();

		//! GetFiles
		/*!
			Funkcia navrati vsetky subory ktore sa maju extrahovat
			\return kolekcia(vektor) suborov na extrakciu
		*/
		std::vector<MetaFile> GetFilesToExtract();


		//! GetName
		/*!
 			Ziska nazov schemy
			\return nazov schemy
		*/
		const std::string& GetName() const;

	private:
		std::string myClassName;
		char myType[4];
		std::vector<MetaDirectory> myRootDirectories;
		std::vector<MetaFile> myRootFiles;
		std::vector<MetaFile> myFilesToExtract;
		bool CompareDirectories(MetaDirectory theOne,MetaDirectory theSecond);
		void get_files(MetaDirectory theDir);
};


//! Funktor Scheme rovnosti.
/*!
 	Funktor na pouzitie ako porovnavac Schemy s nejakym nazvom schemy.
	Mozne pouzitie v std::find_if atd...
*/
class SchemeMatch : public std::unary_function<Scheme, bool>
{
	public:
		SchemeMatch(std::string &theMatch)
		{
			myMatch = theMatch;
		}

		result_type operator()(const argument_type &toMatch)
		{
			if(toMatch.GetName().compare(myMatch) == 0)
				return true;

			return false;
		}

	private:
		std::string myMatch;
};

}

#endif
